import { createTool } from '@mastra/core/tools';
import { z } from 'zod';

/**
 * 线索分析工具
 * 专门处理线索关联分析、调查建议生成、推理假设构建等核心分析功能
 */
export const clueAnalysisTool = createTool({
  id: 'clue-analysis',
  description: '线索分析工具，负责处理调查分析的所有核心逻辑',
  inputSchema: z.object({
    action: z.enum([
      'analyze_clues',
      'suggest_direction',
      'evaluate_progress',
      'identify_gaps',
      'generate_hypothesis',
      'full_analysis'
    ]).describe('要执行的分析操作类型'),
    
    // 案件信息
    caseData: z.object({
      case: z.object({
        title: z.string(),
        description: z.string(),
        location: z.string().optional(),
        timeOfCrime: z.string().optional(),
        victim: z.string().optional()
      }),
      suspects: z.array(z.object({
        id: z.string(),
        name: z.string(),
        personality: z.string(),
        background: z.string(),
        alibi: z.string(),
        suspicionLevel: z.number().optional(),
        isCulprit: z.boolean().optional()
      })).optional(),
      initialClues: z.array(z.any()).optional()
    }).describe('案件基本数据'),
    
    // 线索信息
    discoveredClues: z.array(z.object({
      id: z.string(),
      description: z.string(),
      type: z.string(),
      importance: z.number(),
      isRevealed: z.boolean().optional(),
      relatedSuspects: z.array(z.string()).optional()
    })).optional().describe('已发现的线索'),
    
    // 对话历史
    conversationHistory: z.array(z.object({
      role: z.enum(['detective', 'suspect']),
      content: z.string(),
      suspectId: z.string().optional(),
      timestamp: z.string().optional()
    })).optional().describe('对话历史记录'),
    
    // 游戏上下文
    gameContext: z.object({
      timeRemaining: z.number().optional(),
      conversationCount: z.number().optional(),
      suspectInteractions: z.record(z.number()).optional(),
      difficulty: z.string().optional()
    }).optional().describe('游戏上下文信息'),
    
    // 特定分析参数
    targetSuspect: z.string().optional().describe('目标嫌疑人ID'),
    analysisDepth: z.enum(['basic', 'detailed', 'comprehensive']).optional().describe('分析深度'),
    focusArea: z.string().optional().describe('重点分析领域')
  }),
  outputSchema: z.object({
    success: z.boolean().describe('分析是否成功'),
    analysis: z.string().describe('分析结果描述'),
    clueConnections: z.array(z.object({
      clue1: z.string(),
      clue2: z.string(),
      relationship: z.string(),
      strength: z.number()
    })).optional().describe('线索关联关系'),
    suggestions: z.array(z.string()).describe('调查建议'),
    hypotheses: z.array(z.object({
      culprit: z.string(),
      confidence: z.number(),
      reasoning: z.string(),
      supportingEvidence: z.array(z.string()),
      weaknesses: z.array(z.string())
    })).optional().describe('推理假设'),
    progress: z.object({
      completeness: z.number(),
      confidence: z.number(),
      nextSteps: z.array(z.string())
    }).describe('调查进度评估'),
    gaps: z.array(z.object({
      type: z.string(),
      description: z.string(),
      priority: z.number()
    })).optional().describe('信息缺口'),
    riskAssessment: z.object({
      timeRisk: z.string(),
      evidenceRisk: z.string(),
      overallRisk: z.string()
    }).optional().describe('风险评估'),
    message: z.string().describe('操作结果消息')
  }),
  execute: async ({ context }) => {
    const { 
      action, 
      caseData, 
      discoveredClues = [], 
      conversationHistory = [], 
      gameContext = {} 
    } = context;
    
    try {
      console.log(`线索分析工具执行操作: ${action}`);
      
      switch (action) {
        case 'analyze_clues':
          return await analyzeClueConnections(discoveredClues, caseData);
          
        case 'suggest_direction':
          return await suggestInvestigationDirection(caseData, discoveredClues, conversationHistory, gameContext);
          
        case 'evaluate_progress':
          return await evaluateInvestigationProgress(caseData, discoveredClues, conversationHistory, gameContext);
          
        case 'identify_gaps':
          return await identifyInformationGaps(caseData, discoveredClues, conversationHistory);
          
        case 'generate_hypothesis':
          return await generateInvestigationHypotheses(caseData, discoveredClues, conversationHistory);
          
        case 'full_analysis':
          return await performFullAnalysis(caseData, discoveredClues, conversationHistory, gameContext);
          
        default:
          return {
            success: false,
            analysis: '未知的分析操作类型',
            suggestions: [],
            progress: { completeness: 0, confidence: 0, nextSteps: [] },
            message: `未知的操作类型: ${action}`
          };
      }
    } catch (error) {
      console.error(`线索分析工具操作失败 [${action}]:`, error);
      return {
        success: false,
        analysis: '分析过程中出现错误，请稍后重试',
        suggestions: ['继续收集线索', '与嫌疑人对话', '仔细观察细节'],
        progress: { completeness: 0, confidence: 0, nextSteps: ['重新开始分析'] },
        message: `操作失败: ${error instanceof Error ? error.message : '未知错误'}`
      };
    }
  },
});

/**
 * 分析线索关联关系
 */
async function analyzeClueConnections(clues: any[], caseData: any) {
  const connections = [];
  
  // 分析线索间的关联
  for (let i = 0; i < clues.length; i++) {
    for (let j = i + 1; j < clues.length; j++) {
      const clue1 = clues[i];
      const clue2 = clues[j];
      
      const connection = findClueConnection(clue1, clue2);
      if (connection.strength > 0) {
        connections.push({
          clue1: clue1.description,
          clue2: clue2.description,
          relationship: connection.relationship,
          strength: connection.strength
        });
      }
    }
  }
  
  // 按关联强度排序
  connections.sort((a, b) => b.strength - a.strength);
  
  const analysis = generateConnectionAnalysis(connections, clues);
  
  return {
    success: true,
    analysis,
    clueConnections: connections,
    suggestions: generateConnectionSuggestions(connections),
    progress: {
      completeness: Math.min((clues.length / 5) * 100, 100),
      confidence: Math.min((connections.length / 3) * 100, 100),
      nextSteps: ['寻找更多支持证据', '验证线索关联性']
    },
    message: `分析了${clues.length}条线索，发现${connections.length}个关联关系`
  };
}

/**
 * 建议调查方向
 */
async function suggestInvestigationDirection(caseData: any, clues: any[], conversations: any[], gameContext: any) {
  const suggestions = [];
  const { timeRemaining = 180, suspectInteractions = {} } = gameContext;
  
  // 基于时间压力的建议
  if (timeRemaining < 60) {
    suggestions.push('时间紧迫，专注于最可疑的嫌疑人');
    suggestions.push('快速验证关键证据');
  } else if (timeRemaining > 120) {
    suggestions.push('时间充足，可以深入调查每个嫌疑人');
    suggestions.push('仔细收集所有可能的线索');
  }
  
  // 基于线索数量的建议
  if (clues.length < 3) {
    suggestions.push('线索不足，需要更多对话收集信息');
    suggestions.push('询问嫌疑人的不在场证明');
  } else if (clues.length > 7) {
    suggestions.push('线索丰富，开始分析关联性');
    suggestions.push('准备提交推理结果');
  }
  
  // 基于嫌疑人互动的建议
  const uninteractedSuspects = caseData.suspects?.filter((suspect: any) => 
    !suspectInteractions[suspect.id]
  ) || [];
  
  if (uninteractedSuspects.length > 0) {
    suggestions.push(`还有${uninteractedSuspects.length}个嫌疑人未对话`);
    suggestions.push(`优先与${uninteractedSuspects[0]?.name}对话`);
  }
  
  // 基于线索类型的建议
  const evidenceTypes = clues.map(clue => clue.type);
  if (!evidenceTypes.includes('physical')) {
    suggestions.push('缺少物理证据，询问现场情况');
  }
  if (!evidenceTypes.includes('testimony')) {
    suggestions.push('缺少证人证言，深入对话');
  }
  
  return {
    success: true,
    analysis: '基于当前调查状况生成的方向建议',
    suggestions,
    progress: {
      completeness: calculateCompleteness(clues, conversations, caseData),
      confidence: calculateConfidence(clues, conversations),
      nextSteps: suggestions.slice(0, 3)
    },
    message: `生成了${suggestions.length}条调查建议`
  };
}

/**
 * 评估调查进度
 */
async function evaluateInvestigationProgress(caseData: any, clues: any[], conversations: any[], gameContext: any) {
  const { timeRemaining = 180 } = gameContext;
  
  // 计算各项完成度
  const evidenceCompleteness = Math.min((clues.length / 5) * 100, 100);
  const conversationCompleteness = Math.min((conversations.length / 10) * 100, 100);
  const suspectCoverage = calculateSuspectCoverage(caseData.suspects, conversations);
  
  const overallCompleteness = (evidenceCompleteness + conversationCompleteness + suspectCoverage) / 3;
  
  // 计算信心度
  const highImportanceClues = clues.filter(clue => clue.importance >= 7).length;
  const confidence = Math.min((highImportanceClues / 3) * 100, 100);
  
  // 生成下一步建议
  const nextSteps = [];
  if (evidenceCompleteness < 50) {
    nextSteps.push('收集更多证据线索');
  }
  if (conversationCompleteness < 50) {
    nextSteps.push('增加与嫌疑人的对话');
  }
  if (suspectCoverage < 80) {
    nextSteps.push('确保与所有嫌疑人都有对话');
  }
  if (overallCompleteness > 70) {
    nextSteps.push('准备分析推理结果');
  }
  
  // 风险评估
  const riskAssessment = {
    timeRisk: timeRemaining < 60 ? 'high' : timeRemaining < 120 ? 'medium' : 'low',
    evidenceRisk: clues.length < 3 ? 'high' : clues.length < 5 ? 'medium' : 'low',
    overallRisk: overallCompleteness < 30 ? 'high' : overallCompleteness < 60 ? 'medium' : 'low'
  };
  
  return {
    success: true,
    analysis: `调查进度评估：整体完成度${Math.round(overallCompleteness)}%，信心度${Math.round(confidence)}%`,
    suggestions: generateProgressSuggestions(overallCompleteness, confidence, timeRemaining),
    progress: {
      completeness: overallCompleteness,
      confidence,
      nextSteps
    },
    riskAssessment,
    message: '调查进度评估完成'
  };
}

/**
 * 识别信息缺口
 */
async function identifyInformationGaps(caseData: any, clues: any[], conversations: any[]) {
  const gaps = [];
  
  // 检查证据类型缺口
  const evidenceTypes = new Set(clues.map(clue => clue.type));
  if (!evidenceTypes.has('physical')) {
    gaps.push({
      type: 'evidence',
      description: '缺少物理证据',
      priority: 8
    });
  }
  if (!evidenceTypes.has('testimony')) {
    gaps.push({
      type: 'evidence',
      description: '缺少证人证言',
      priority: 7
    });
  }
  
  // 检查嫌疑人信息缺口
  const discussedSuspects = new Set(
    conversations
      .filter(conv => conv.suspectId)
      .map(conv => conv.suspectId)
  );
  
  caseData.suspects?.forEach((suspect: any) => {
    if (!discussedSuspects.has(suspect.id)) {
      gaps.push({
        type: 'suspect',
        description: `未与${suspect.name}进行对话`,
        priority: 6
      });
    }
  });
  
  // 检查关键问题缺口
  const questionTypes = conversations.map(conv => categorizeQuestion(conv.content));
  if (!questionTypes.includes('alibi')) {
    gaps.push({
      type: 'question',
      description: '缺少不在场证明询问',
      priority: 9
    });
  }
  if (!questionTypes.includes('motive')) {
    gaps.push({
      type: 'question',
      description: '缺少动机分析',
      priority: 8
    });
  }
  
  // 按优先级排序
  gaps.sort((a, b) => b.priority - a.priority);
  
  return {
    success: true,
    analysis: `识别出${gaps.length}个信息缺口`,
    gaps,
    suggestions: gaps.slice(0, 3).map(gap => `解决${gap.description}`),
    progress: {
      completeness: Math.max(100 - gaps.length * 10, 0),
      confidence: Math.max(100 - gaps.filter(g => g.priority > 7).length * 20, 0),
      nextSteps: gaps.slice(0, 3).map(gap => gap.description)
    },
    message: '信息缺口分析完成'
  };
}

/**
 * 生成调查假设
 */
async function generateInvestigationHypotheses(caseData: any, clues: any[], conversations: any[]) {
  const hypotheses = [];
  
  if (caseData.suspects) {
    for (const suspect of caseData.suspects) {
      const supportingEvidence = clues.filter(clue => 
        clue.description.includes(suspect.name) || 
        clue.relatedSuspects?.includes(suspect.id)
      );
      
      const suspectConversations = conversations.filter(conv => conv.suspectId === suspect.id);
      
      const confidence = calculateSuspectConfidence(suspect, supportingEvidence, suspectConversations);
      
      const hypothesis = {
        culprit: suspect.name,
        confidence,
        reasoning: generateReasoning(suspect, supportingEvidence, suspectConversations),
        supportingEvidence: supportingEvidence.map(clue => clue.description),
        weaknesses: identifyHypothesisWeaknesses(suspect, supportingEvidence, suspectConversations)
      };
      
      hypotheses.push(hypothesis);
    }
  }
  
  // 按信心度排序
  hypotheses.sort((a, b) => b.confidence - a.confidence);
  
  return {
    success: true,
    analysis: `生成了${hypotheses.length}个推理假设`,
    hypotheses,
    suggestions: [
      `最可能的嫌疑人是${hypotheses[0]?.culprit}`,
      '收集更多支持证据',
      '验证推理逻辑'
    ],
    progress: {
      completeness: Math.min((hypotheses.length / caseData.suspects?.length || 1) * 100, 100),
      confidence: hypotheses[0]?.confidence || 0,
      nextSteps: ['验证最强假设', '寻找反驳证据']
    },
    message: '推理假设生成完成'
  };
}

/**
 * 执行完整分析
 */
async function performFullAnalysis(caseData: any, clues: any[], conversations: any[], gameContext: any) {
  // 执行所有分析步骤
  const clueAnalysis = await analyzeClueConnections(clues, caseData);
  const directionSuggestion = await suggestInvestigationDirection(caseData, clues, conversations, gameContext);
  const progressEvaluation = await evaluateInvestigationProgress(caseData, clues, conversations, gameContext);
  const gapIdentification = await identifyInformationGaps(caseData, clues, conversations);
  const hypothesesGeneration = await generateInvestigationHypotheses(caseData, clues, conversations);
  
  // 综合分析结果
  const comprehensiveAnalysis = `
    ## 综合调查分析报告
    
    ### 线索关联分析
    ${clueAnalysis.analysis}
    发现${clueAnalysis.clueConnections?.length || 0}个线索关联关系。
    
    ### 调查进度评估
    ${progressEvaluation.analysis}
    
    ### 信息缺口识别
    识别出${gapIdentification.gaps?.length || 0}个关键信息缺口。
    
    ### 推理假设
    ${hypothesesGeneration.analysis}
    最可能的嫌疑人：${hypothesesGeneration.hypotheses?.[0]?.culprit || '待确定'}
    
    ### 建议行动
    ${directionSuggestion.suggestions.slice(0, 3).join('；')}
  `;
  
  return {
    success: true,
    analysis: comprehensiveAnalysis,
    clueConnections: clueAnalysis.clueConnections,
    suggestions: directionSuggestion.suggestions,
    hypotheses: hypothesesGeneration.hypotheses,
    progress: progressEvaluation.progress,
    gaps: gapIdentification.gaps,
    riskAssessment: progressEvaluation.riskAssessment,
    message: '完整分析报告生成完成'
  };
}

// 辅助函数
function findClueConnection(clue1: any, clue2: any) {
  let strength = 0;
  let relationship = '';
  
  // 检查时间关联
  if (clue1.description.includes('时间') && clue2.description.includes('时间')) {
    strength += 3;
    relationship = '时间关联';
  }
  
  // 检查地点关联
  if (clue1.description.includes('现场') && clue2.description.includes('现场')) {
    strength += 3;
    relationship = '地点关联';
  }
  
  // 检查人物关联
  const commonWords = findCommonWords(clue1.description, clue2.description);
  if (commonWords.length > 0) {
    strength += commonWords.length;
    relationship = '内容关联';
  }
  
  return { strength, relationship };
}

function findCommonWords(text1: string, text2: string): string[] {
  const words1 = text1.split(/\s+/);
  const words2 = text2.split(/\s+/);
  return words1.filter(word => words2.includes(word) && word.length > 1);
}

function generateConnectionAnalysis(connections: any[], clues: any[]): string {
  if (connections.length === 0) {
    return '当前线索之间暂未发现明显关联，建议收集更多信息。';
  }
  
  const strongConnections = connections.filter(conn => conn.strength >= 3);
  return `分析发现${connections.length}个线索关联，其中${strongConnections.length}个为强关联。${
    strongConnections.length > 0 ? '重点关注强关联线索的深入分析。' : '建议寻找更多相关证据。'
  }`;
}

function generateConnectionSuggestions(connections: any[]): string[] {
  const suggestions = ['继续收集线索验证关联性'];
  
  if (connections.length > 0) {
    suggestions.push('深入分析最强的线索关联');
    suggestions.push('寻找支持关联关系的额外证据');
  } else {
    suggestions.push('扩大调查范围寻找线索关联');
    suggestions.push('从不同角度重新审视现有线索');
  }
  
  return suggestions;
}

function calculateCompleteness(clues: any[], conversations: any[], caseData: any): number {
  const clueScore = Math.min((clues.length / 5) * 40, 40);
  const conversationScore = Math.min((conversations.length / 8) * 40, 40);
  const suspectScore = calculateSuspectCoverage(caseData.suspects, conversations) * 0.2;
  
  return clueScore + conversationScore + suspectScore;
}

function calculateConfidence(clues: any[], conversations: any[]): number {
  const highImportanceClues = clues.filter(clue => clue.importance >= 7).length;
  const meaningfulConversations = conversations.filter(conv => conv.content.length > 20).length;
  
  return Math.min((highImportanceClues * 25) + (meaningfulConversations * 5), 100);
}

function calculateSuspectCoverage(suspects: any[], conversations: any[]): number {
  if (!suspects || suspects.length === 0) return 100;
  
  const discussedSuspects = new Set(
    conversations
      .filter(conv => conv.suspectId)
      .map(conv => conv.suspectId)
  );
  
  return (discussedSuspects.size / suspects.length) * 100;
}

function generateProgressSuggestions(completeness: number, confidence: number, timeRemaining: number): string[] {
  const suggestions = [];
  
  if (completeness < 50) {
    suggestions.push('调查进度偏慢，需要加快收集线索');
  }
  if (confidence < 50) {
    suggestions.push('证据质量不足，寻找更重要的线索');
  }
  if (timeRemaining < 60) {
    suggestions.push('时间紧迫，专注于最关键的调查方向');
  }
  if (completeness > 70 && confidence > 70) {
    suggestions.push('调查进展良好，可以开始准备推理结论');
  }
  
  return suggestions;
}

function categorizeQuestion(question: string): string {
  if (question.includes('在哪') || question.includes('时间')) return 'alibi';
  if (question.includes('为什么') || question.includes('动机')) return 'motive';
  if (question.includes('看到') || question.includes('听到')) return 'evidence';
  if (question.includes('关系') || question.includes('认识')) return 'relationship';
  return 'general';
}

function calculateSuspectConfidence(suspect: any, evidence: any[], conversations: any[]): number {
  let confidence = suspect.suspicionLevel || 5;
  
  // 证据加分
  confidence += evidence.length * 10;
  
  // 对话质量加分
  const meaningfulConversations = conversations.filter(conv => conv.content.length > 30);
  confidence += meaningfulConversations.length * 5;
  
  // 重要证据加分
  const highImportanceEvidence = evidence.filter(e => e.importance >= 7);
  confidence += highImportanceEvidence.length * 15;
  
  return Math.min(confidence, 100);
}

function generateReasoning(suspect: any, evidence: any[], conversations: any[]): string {
  const reasons = [];
  
  if (suspect.suspicionLevel > 7) {
    reasons.push('基础可疑程度较高');
  }
  
  if (evidence.length > 0) {
    reasons.push(`有${evidence.length}条相关证据支持`);
  }
  
  if (conversations.length > 0) {
    reasons.push('对话中表现出可疑行为');
  }
  
  return reasons.join('；') || '基于当前信息的初步判断';
}

function identifyHypothesisWeaknesses(suspect: any, evidence: any[], conversations: any[]): string[] {
  const weaknesses = [];
  
  if (evidence.length < 2) {
    weaknesses.push('支持证据不足');
  }
  
  if (conversations.length < 2) {
    weaknesses.push('对话信息有限');
  }
  
  if (suspect.suspicionLevel < 6) {
    weaknesses.push('基础可疑程度较低');
  }
  
  const lowImportanceEvidence = evidence.filter(e => e.importance < 5);
  if (lowImportanceEvidence.length === evidence.length) {
    weaknesses.push('证据重要性不高');
  }
  
  return weaknesses;
}
